package com.lysj.bhp.coinexchange.service;

import com.google.gson.Gson;
import com.lysj.bhp.coinexchange.base.CoinExchangeContent;
import com.lysj.bhp.coinexchange.domain.Apply;
import com.lysj.bhp.coinexchange.domain.BhpcRecord;
import com.lysj.bhp.exchangerate.json.bcexv2.BcexRateResp;
import com.lysj.bhp.exchangerate.json.bcexv2.Data;
import com.lysj.bhp.util.http.HttpUtil;
import com.lysj.bhp.util.random.FormatUtil;
import com.lysj.bhp.util.random.RandomUtil;
import com.lysj.bhp.util.web.ParamUtil;
import com.lysj.bhp.util.web.Resp;
import com.lysj.bhp.wallet.domain.BhpcWallet;
import com.lysj.bhp.wallet.domain.BitCoinWallet;
import com.lysj.bhp.wallet.domain.EthereumWallet;
import io.bumo.crypto.protobuf.Monitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class ApplyService extends CoinExchangeContent {

    private static Logger logger = LoggerFactory.getLogger(ApplyService.class);

    private static BigDecimal BHPC_TO_ETHEREUM = new BigDecimal("-1"); // 算力币对以太币的汇率
    private static long BHPC_TO_ETHEREUM_EXPIRES = 0; //缓存有效时间

    private static BigDecimal BHPC_TO_BITCOIN = new BigDecimal("-1"); //算力币大于比特币对应美元汇率
    private static long BHPC_TO_BITCOIN_EXPIRES = 0; //缓存有效时间

    private static final long FIVE_SECOND = 1000 * 5;

    private static final long TEN_SECOND = 1000 * 10;

    private static String BCEX_TIKER_URL = "https://www.bcex.top/Api_Order/ticker";

    private static BigDecimal EXCHANGE_MAX_LIMIT = new BigDecimal("10000");

    private static BigDecimal EXCHANGE_ONE_AMOUNT = new BigDecimal("1000");

    public synchronized Resp buyBhpcByUser(BhpcRecord model, int type, String password) throws Exception {
        if (ParamUtil.isBlack(password)) {
            return new Resp(Resp.PARAM_ERROR, "请输入交易密码");
        }
        if (!ParamUtil.md5(password).equals(currentUser().getTradePassword())) {
            return new Resp(Resp.PARAM_ERROR, "交易密码错误");
        }
        if (null == model.getExchangeNum()) {
            return new Resp(Resp.PARAM_ERROR, "请输入交易金额");
        }
        if (model.getExchangeNum().compareTo(BigDecimal.ZERO) != 1) {
            return new Resp(Resp.PARAM_ERROR, "金额输入必须大于0");
        }

        //如果用户没创建bhpc钱包,则创建bhpc钱包
        BhpcWallet bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
        if (ParamUtil.isBlack(bhpcWallet)) {
            walletService.myBhpcWallet();
            bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
        }
        //查询用户当日的兑换记录,获取bhpc数量
        List<BhpcRecord> bhpcRecordList = bhpcRecordRepository.findByUserIdAndCreateDateBetween(currentUser().getUserId(), FormatUtil.getDayStartDay(new Date()), FormatUtil.getDayEndDay(new Date()));
        BigDecimal amount = new BigDecimal(BigInteger.ZERO);
        for (BhpcRecord bhpcRecord : bhpcRecordList) {
            amount = amount.add(bhpcRecord.getBhpc());
        }
        BhpcRecord bhpcRecord = new BhpcRecord();  // 兑换记录
        bhpcRecord.setBhpcToDollar(exchangeRateService.getBhpcToDollar());
        bhpcRecord.setCreateDate(new Date());
        bhpcRecord.setUserId(currentUser().getUserId());
        bhpcRecord.setWhitelist(0);
        bhpcRecord.setExchangeNum(model.getExchangeNum());

        BigDecimal exchangeAmount;
        //用户用比特币钱包兑换BHPC币
        if (type == 10) {
            //兑换数量
            exchangeAmount = new BigDecimal("1").divide(getBhpcToBitcoin(), 18, BigDecimal.ROUND_DOWN).multiply(model.getExchangeNum());
            //当笔数额判定
            if (exchangeAmount.compareTo(EXCHANGE_ONE_AMOUNT) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "当笔兑换BHPC数量最多为1000个");
            }
            //每日限额10000
            if ((exchangeAmount.add(amount)).compareTo(EXCHANGE_MAX_LIMIT) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "当日兑换BHPC数量最多为10000个");
            }
            BitCoinWallet bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
            if (ParamUtil.isBlack(bitCoinWallet)) {
                return new Resp(Resp.PARAM_ERROR, "金额不足,请先充值");
            }
            if (model.getExchangeNum().compareTo(bitCoinWallet.getAvailBalance()) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "金额不足");
            }
            bitCoinWallet.setBalance(bitCoinWallet.getBalance().subtract(model.getExchangeNum()));
            bitCoinWallet.setAvailBalance(bitCoinWallet.getAvailBalance().subtract(model.getExchangeNum()));
            bitcoinWalletRepository.save(bitCoinWallet);

            bhpcRecord.setExchangeRate(getBhpcToBitcoin());
            bhpcRecord.setType(10);

        } else if (type == 20) {
            exchangeAmount = new BigDecimal("1").divide(getBhpcToEthereum(), 18, BigDecimal.ROUND_DOWN).multiply(model.getExchangeNum());
            //当笔数额判定
            if (exchangeAmount.compareTo(EXCHANGE_ONE_AMOUNT) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "当笔兑换BHPC数量最多为1000个");
            }
            //每日限额10000
            if ((exchangeAmount.add(amount)).compareTo(EXCHANGE_MAX_LIMIT) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "当日兑换BHPC数量最多为10000个");
            }
            EthereumWallet ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
            if (ParamUtil.isBlack(ethereumWallet)) {
                return new Resp(Resp.PARAM_ERROR, "金额不足,请先充值");
            }
            if (model.getExchangeNum().compareTo(ethereumWallet.getAvailBalance()) >= 1) {
                return new Resp(Resp.PARAM_ERROR, "金额不足");
            }
            ethereumWallet.setBalance(ethereumWallet.getBalance().subtract(model.getExchangeNum()));
            ethereumWallet.setAvailBalance(ethereumWallet.getAvailBalance().subtract(model.getExchangeNum()));
            ethereumWalletRepository.save(ethereumWallet);

            bhpcRecord.setExchangeRate(getBhpcToEthereum());
            bhpcRecord.setType(20);
        } else {
            return new Resp(Resp.PARAM_ERROR, "币种类型错误");
        }

        BigDecimal toBhpcCount = bhpcRecord.getExchangeNum().divide(bhpcRecord.getExchangeRate(), 18, BigDecimal.ROUND_DOWN);

        bhpcRecord.setBhpc(toBhpcCount); //通过计算获得Bhpc的数量
        bhpcRecord.setStatus("成功");

        //改变用户BHPC钱包余额
        bhpcWallet.setBalance(bhpcWallet.getBalance().add(toBhpcCount));
        bhpcWallet.setAvailBalance(bhpcWallet.getAvailBalance().add(toBhpcCount));
        bhpcWalletRepository.save(bhpcWallet);
        bhpcRecordRepository.save(bhpcRecord);
        logger.info(currentUser().getEmail() + "->购买了:" + toBhpcCount + " 个算力币!!");
        return new Resp("兑换成功");
    }


    public BigDecimal getBhpcToEthereum() {
        if (System.currentTimeMillis() < BHPC_TO_ETHEREUM_EXPIRES) { // 还在缓存期内
            return BHPC_TO_ETHEREUM;
        }

        String respJson = HttpUtil.sendGet(BCEX_TIKER_URL, "symbol=bhpc2eth");
        if (ParamUtil.isBlack(respJson)) {
            return BHPC_TO_ETHEREUM;
        }
        BcexRateResp bcexRateResp = new Gson().fromJson(respJson, BcexRateResp.class);
        if (bcexRateResp == null) {
            logger.error("Json格式化错误:" + respJson);
            return BHPC_TO_ETHEREUM;
        }
        if (bcexRateResp.getCode() != 0) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_ETHEREUM;
        }
        Data data = bcexRateResp.getData();
        if (data == null) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_ETHEREUM;
        }

        if (ParamUtil.isBlack(data.getSell())) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_ETHEREUM;
        }
        BigDecimal bhpcToEthRate = new BigDecimal(data.getSell());
        logger.info("[bcex内部接口]算力币对以太坊汇率:" + bhpcToEthRate);
        BHPC_TO_ETHEREUM = bhpcToEthRate.multiply(new BigDecimal(1.01)); // 价格上浮1%
        BHPC_TO_ETHEREUM_EXPIRES = System.currentTimeMillis() + RandomUtil.getRandomNum(FIVE_SECOND, TEN_SECOND);
        return BHPC_TO_ETHEREUM;
    }

    public BigDecimal getBhpcToBitcoin() {
        if (System.currentTimeMillis() < BHPC_TO_BITCOIN_EXPIRES) { // 还在缓存期内
            return BHPC_TO_BITCOIN;
        }

        String respJson = HttpUtil.sendGet(BCEX_TIKER_URL, "symbol=bhpc2btc");
        if (ParamUtil.isBlack(respJson)) {
            return BHPC_TO_BITCOIN;
        }
        BcexRateResp bcexRateResp = new Gson().fromJson(respJson, BcexRateResp.class);
        if (bcexRateResp == null) {
            logger.error("Json格式化错误:" + respJson);
            return BHPC_TO_BITCOIN;
        }
        if (bcexRateResp.getCode() != 0) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_BITCOIN;
        }
        Data data = bcexRateResp.getData();
        if (data == null) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_BITCOIN;
        }

        if (ParamUtil.isBlack(data.getSell())) {
            logger.error("接口数据错误:" + respJson);
            return BHPC_TO_BITCOIN;
        }
        BigDecimal bhpcToEthRate = new BigDecimal(data.getSell());
        logger.info("[bcex内部接口]算力币对比特币汇率:" + bhpcToEthRate);
        BHPC_TO_BITCOIN = bhpcToEthRate.multiply(new BigDecimal(1.01)); // 价格上浮1%
        BHPC_TO_BITCOIN_EXPIRES = System.currentTimeMillis() + RandomUtil.getRandomNum(FIVE_SECOND, TEN_SECOND);
        return BHPC_TO_BITCOIN;
    }


}
